package com.demo.search.util;

import java.io.File;
import java.io.IOException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.NumericField;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.IndexWriterConfig.OpenMode;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.store.NRTCachingDirectory;
import org.apache.lucene.util.Version;
import org.wltea.analyzer.lucene.IKAnalyzer;

import com.demo.common.StringUtils;

/**
 * Lucene检索工具
 * 
 * @author ryuu.kk
 * 
 */
public abstract class LuceneUtils {

	/**
	 * 最大合并字节(MB)
	 */
	private static final double MAX_MEGER_SIZE_MB = 5.0;
	
	/**
	 * 最大缓存字节(MB)
	 */
	private static final double MAX_CACHED_SIZE_MB = 60.0;
	
	/**
	 * 创建NRTCachingDirectory
	 * @param indexPath
	 * @param maxMergeSizeMB
	 * @param maxCachedMB
	 * @return Directory
	 * @throws IOException
	 */
	public static Directory createFSDriectory(String indexPath, double maxMergeSizeMB, double maxCachedMB) throws IOException {
		Directory fsDir = FSDirectory.open(new File(indexPath));
		NRTCachingDirectory cachedFSDir = new NRTCachingDirectory(fsDir, maxMergeSizeMB, maxCachedMB);
		return cachedFSDir;
	}
	
	/**
	 * 创建NRTCachingDirectory
	 * @param indexPath
	 * @return Directory
	 * @throws IOException
	 */
	public static Directory createFSDriectory(String indexPath) throws IOException {
		return createFSDriectory(indexPath, MAX_MEGER_SIZE_MB, MAX_CACHED_SIZE_MB);
	}
	
	/**
	 * 根据创建文件存储为基础的IndexWriter
	 * @param indexPath 索引文件地址
	 * @param analyzer 分析器
	 * @param openMode 索引写入模式(创建、)
	 * @return IndexWriter 写索引
	 * @throws IOException IO异常
	 */
	public static IndexWriter createFSIndexWriter(String indexPath, Analyzer analyzer) throws IOException {
		return buildFSIndexWriter(indexPath, analyzer, OpenMode.CREATE, Version.LUCENE_36, MAX_MEGER_SIZE_MB, MAX_CACHED_SIZE_MB);
	}
	
	/**
	 * 根据创建文件存储为基础的IndexWriter
	 * @param indexPath
	 * @param analyzer
	 * @return
	 * @throws IOException
	 */
	public static IndexWriter openFSIndexWriter(String indexPath, Analyzer analyzer) throws IOException {
		return buildFSIndexWriter(indexPath, analyzer, OpenMode.CREATE_OR_APPEND, Version.LUCENE_36, MAX_MEGER_SIZE_MB, MAX_CACHED_SIZE_MB);
	}
	
	/**
	 * 根据创建文件存储为基础的IndexWriter
	 * @param indexPath 索引文件存放位置
	 * @param analyzer 分析器
	 * @param version 版本
	 * @param maxMergeSizeMB 最大合并段大小
	 * @param maxCachedMB 最大缓存段大小
	 * @return IndexWriter 写索引
	 * @throws IOException IO异常
	 */
	public static IndexWriter buildFSIndexWriter(String indexPath, Analyzer analyzer, OpenMode openMode, Version version, double maxMergeSizeMB, double maxCachedMB) throws IOException {
		Directory fsDir = FSDirectory.open(new File(indexPath));
		NRTCachingDirectory cachedFSDir = new NRTCachingDirectory(fsDir, maxMergeSizeMB, maxCachedMB);
		IndexWriterConfig conf = new IndexWriterConfig(version, analyzer);
		conf.setMergeScheduler(cachedFSDir.getMergeScheduler());
		conf.setOpenMode(openMode);
		IndexWriter writer = new IndexWriter(cachedFSDir, conf);
		return writer;
	}
	
	/**
	 * 创建中文分词器
	 * @return Analyzer
	 */
	public static Analyzer createChineseAnalyzer() {
		// 分词器
		Analyzer analyzer = new IKAnalyzer(true);
		return analyzer;
	}
	
	/**
	 * 创建一般类型分词器
	 * @return Analyzer
	 */
	public static Analyzer createStandardAnalyzer() {
		return new StandardAnalyzer(Version.LUCENE_36);
	}
	
	public static void setValue(NumericField field, Object value, Class<?> type, String converter) {
		if (value != null) {
			if (type.equals(java.lang.Long.class)) {
				field.setLongValue(Long.parseLong(value.toString()));
			} else if (type.equals(java.lang.Integer.class)) {
				field.setIntValue(Integer.parseInt(value.toString()));
			} else if (type.equals(java.lang.Double.class)) {
				field.setDoubleValue(Double.parseDouble(value.toString()));
			} else if (type.equals(java.lang.Float.class)) {
				field.setFloatValue(Float.parseFloat(value.toString()));
			} else {
				// 使用覆盖器？
			}
		}
	}
	
	public static Object typeTrans(Object value, Class<?> type) {
		if (value != null) {
			if (type.equals(java.lang.Long.class)) {
				return Long.parseLong(value.toString());
			} else if (type.equals(java.lang.Integer.class)) {
				return Integer.parseInt(value.toString());
			} else if (type.equals(java.lang.Double.class)) {
				return Double.parseDouble(value.toString());
			} else if (type.equals(java.lang.Float.class)) {
				return Float.parseFloat(value.toString());
			} else {
				// 使用覆盖器？
			}
		}
		return value;
	}
	
	/**
	 * 将简单类型对象转换成字符串
	 * @param obj 简单类型对象
	 * @param format Format
	 * @return String 转换后的字符串
	 */
	public static String objectTransformation(Object obj, String format) {
		String value = "";
		if (obj != null) {
			if (obj instanceof java.lang.Long) {
				value = String.valueOf(obj);
			} else if (obj instanceof java.lang.Integer) {
				value = String.valueOf(obj);
			} else if (obj instanceof java.lang.Double) {
				value = String.valueOf(obj);
			} else if (obj instanceof java.lang.Float) {
				value = String.valueOf(obj);
			} else if (obj instanceof java.util.Date) {
				if (StringUtils.isEmpty(format)) {
					format = "yyyy/MM/dd HH:mm:ss";
				}
				DateFormat dtFormat = new SimpleDateFormat(format);
				value = dtFormat.format((Date) obj);
			} else {
				value = obj.toString();
			}
		}
		return value;
	}
	
	/**
	 * 简单类型的类型转换
	 * @param value
	 * @param type
	 * @return
	 */
	public static Object typeTransformation(String value, Class<?> type, String format) {
		if ("null".equals(value)) {
			return null;
		}
		if (value != null) {
			if (type.equals(java.lang.Long.class)) {
				return Long.parseLong(value);
			} else if (type.equals(java.lang.Integer.class)) {
				return Integer.parseInt(value);
			} else if (type.equals(java.lang.Double.class)) {
				return Double.parseDouble(value);
			} else if (type.equals(java.lang.Float.class)) {
				return Float.parseFloat(value);
			} else if (type.equals(java.util.Date.class)){
				// 定义Date
				Date date = null;
				if (StringUtils.isNotEmpty(value)) {
					if (StringUtils.isEmpty(format)) {
						// 默认格式
						format = "yyyy/MM/dd HH:mm:ss";
					}
					DateFormat dtFormat = new SimpleDateFormat(format);
					try {
						date = dtFormat.parse(value);
					} catch (ParseException e) {
						//e.printStackTrace();
						
					}
				}
				return date;
			} else {
				// 使用覆盖器？
				// 
			}
		}
		return value;
	}
}
